package com.jeecms.cms.action.front;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jeecms.cms.Constants;
import com.jeecms.cms.entity.main.Channel;
import com.jeecms.cms.entity.main.ChannelTxt;
import com.jeecms.cms.entity.main.Content;
import com.jeecms.cms.entity.main.ContentCheck;
import com.jeecms.cms.manager.assist.CmsKeywordMng;
import com.jeecms.cms.manager.main.ChannelMng;
import com.jeecms.cms.manager.main.ContentBuyMng;
import com.jeecms.cms.manager.main.ContentMng;
import com.jeecms.cms.web.Token;
import com.jeecms.common.page.Paginable;
import com.jeecms.common.page.SimplePage;
import com.jeecms.common.web.ResponseUtils;
import com.jeecms.common.web.session.SessionProvider;
import com.jeecms.common.web.springmvc.RealPathResolver;
import com.jeecms.core.entity.CmsConfig;
import com.jeecms.core.entity.CmsGroup;
import com.jeecms.core.entity.CmsSite;
import com.jeecms.core.entity.CmsUser;
import com.jeecms.core.manager.CmsSiteMng;
import com.jeecms.core.web.util.CmsUtils;
import com.jeecms.core.web.util.FrontUtils;
import com.jeecms.core.web.util.URLHelper;
import com.jeecms.core.web.util.URLHelper.PageInfo;
import com.jeecms.plug.ali.video.AliVedioApi;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static com.jeecms.cms.Constants.TPLDIR_INDEX;
import static com.jeecms.common.web.Constants.*;

@Controller
public class DynamicPageAct {
	private static final Logger log = LoggerFactory
			.getLogger(DynamicPageAct.class);
	/**
	 * 首页模板名称
	 */
	public static final String TPL_INDEX = "tpl.index";
	public static final String GROUP_FORBIDDEN = "login.groupAccessForbidden";
	public static final String CONTENT_STATUS_FORBIDDEN ="content.notChecked";

	/**
	 * TOMCAT的默认路径
	 * 
	 * @param request
	 * @param model
	 * @return
	 */
	@RequestMapping(value = "/", method = RequestMethod.GET)
	@Token(save=true)
	public String index(HttpServletRequest request,HttpServletResponse response, ModelMap model) {
		CmsSite site = CmsUtils.getSite(request);
		FrontUtils.frontData(request, model, site);
	//	return FrontUtils.getTplPath(request, site.getSolutionPath(),TPLDIR_INDEX, TPL_INDEX);
		//带有其他路径则是非法请求(非内网)
		String uri=URLHelper.getURI(request);
		if(StringUtils.isNotBlank(uri)&&(!(uri.equals("/")||uri.equals("/index.jhtml")))){
			return FrontUtils.pageNotFound(request, response, model);
		}
		//使用静态首页而且静态首页存在
		if(existIndexPage(site)){
			return goToIndexPage(request, response, site);
		}else{
			String tpl = site.getTplIndex();
			if (!StringUtils.isBlank(tpl)) {
				return tpl;
			} else {
				return FrontUtils.getTplPath(request, site.getSolutionPath(),TPLDIR_INDEX, TPL_INDEX);
			}
		}
	}

	/**
	 * WEBLOGIC的默认路径
	 * 
	 * @param request
	 * @param model
	 * @return
	 */
	@RequestMapping(value = "/index.jhtml", method = RequestMethod.GET)
	@Token(save=true)
	public String indexForWeblogic(HttpServletRequest request,HttpServletResponse response, ModelMap model) {
		return index(request, response,model);
	}

	/**
	 * 动态页入口
	 */
	@Token(save=true)
	@RequestMapping(value = "/**/*.*", method = RequestMethod.GET)
	public String dynamic(HttpServletRequest request,
			HttpServletResponse response, ModelMap model) {
		// 尽量不要携带太多参数，多使用标签获取数据。
		// 目前已知的需要携带翻页信息。
		// 获得页号和翻页信息吧。
		int pageNo = URLHelper.getPageNo(request);
		String[] params = URLHelper.getParams(request);
		PageInfo info = URLHelper.getPageInfo(request);
		String[] paths = URLHelper.getPaths(request);
		int len = paths.length;
		if (len == 1) {
			// 单页
			return channel(paths[0],true, pageNo, params, info, request, response,
					model);
		} else if (len == 2) {
			if (paths[1].equals(INDEX)) {
				// 栏目页
				return channel(paths[0],false, pageNo, params, info, request,
						response, model);
			} else {
				// 内容页
				try {
					Integer id = Integer.parseInt(paths[1]);
					return content(id, pageNo, params, info, request, response,
							model);
				} catch (NumberFormatException e) {
					log.debug("Content id must String: {}", paths[1]);
					return FrontUtils.pageNotFound(request, response, model);
				}
			}
		} else {
			log.debug("Illegal path length: {}, paths: {}", len, paths);
			return FrontUtils.pageNotFound(request, response, model);
		}
	}
	
	public String channel(String path,boolean checkAlone, int pageNo, String[] params,
			PageInfo info, HttpServletRequest request,
			HttpServletResponse response, ModelMap model) {
		CmsSite site = CmsUtils.getSite(request);
		Channel channel = channelMng.findByPathForTag(path, site.getId());
		if (channel == null) {
			log.debug("Channel path not found: {}", path);
			return FrontUtils.pageNotFound(request, response, model);
		}
		//检查是否单页
		if(checkAlone){
			if(channel.getHasContent()){
				return FrontUtils.pageNotFound(request, response, model);
			}
            Set<ChannelTxt> channelTxts = channel.getChannelTxtSet();
            Iterator<ChannelTxt> iter = channelTxts.iterator();
            if(iter.hasNext()){
                ChannelTxt txt = iter.next();
                model.addAttribute("chTxt", txt);
            }
		}
		model.addAttribute("channel", channel);
		FrontUtils.frontData(request, model, site);
		FrontUtils.frontPageData(request, model);
		String equipment=(String) request.getAttribute("ua");
		if(StringUtils.isNotBlank(equipment)&&equipment.equals("mobile")){
			return channel.getMobileTplChannelOrDef();
		}
		return channel.getTplChannelOrDef();
	}

	public String content(Integer id, int pageNo, String[] params,
			PageInfo info, HttpServletRequest request,
			HttpServletResponse response, ModelMap model) {
		Content content = contentMng.findById(id);
		if (content == null) {
			log.debug("Content id not found: {}", id);
			return FrontUtils.pageNotFound(request, response, model);
		}
		Integer pageCount=content.getPageCount();
		if(pageNo>pageCount||pageNo<0){
			return FrontUtils.pageNotFound(request, response, model);
		}
		//非终审文章
		CmsConfig config=CmsUtils.getSite(request).getConfig();
		if(config.getViewOnlyChecked()&&!content.getStatus().equals(ContentCheck.CHECKED)){
			return FrontUtils.showMessage(request, model, CONTENT_STATUS_FORBIDDEN);
		}
		CmsSite site = content.getSite();
		String txt = content.getTxtByNo(pageNo);
		// 内容加上关键字
		txt = cmsKeywordMng.attachKeyword(site.getId(), txt);
		Paginable pagination = new SimplePage(pageNo, 1, content.getPageCount());
		model.addAttribute("pagination", pagination);
		FrontUtils.frontPageData(request, model);
		model.addAttribute("content", content);
		model.addAttribute("channel", content.getChannel());
		model.addAttribute("title", content.getTitleByNo(pageNo));
		model.addAttribute("txt", txt);
		String[] attachs = content.getAttachmentPaths();
		if(attachs != null && attachs.length>0)
			model.addAttribute("docPath", attachs[0]);
		model.addAttribute("pic", content.getPictureByNo(pageNo));
		//文库文档转换
		if(attachs != null && attachs.length == 1 && attachs[0].startsWith(Constants.LIBRARY_PATH)){
            //获取文件名字
            String swfFileName = attachs[0].substring(attachs[0].lastIndexOf("/") + 1, attachs[0].length());
            swfFileName = swfFileName.substring(0, swfFileName.lastIndexOf("."));
            //获取文件路径
            String filePath = attachs[0].substring(0,attachs[0].lastIndexOf("/"));
            // 将相对路径放入sessio中保存
            model.addAttribute("swfPath", site.getContextPath() + filePath +  "/" + swfFileName + ".pdf");
		}
		FrontUtils.frontData(request, model, site);
		String equipment=(String) request.getAttribute("ua");
		if(StringUtils.isNotBlank(equipment)&&equipment.equals("mobile")){
			return content.getMobileTplContentOrDef(content.getModel());
		}
		return content.getTplContentOrDef(content.getModel());
	}

	/**
	 * 视频播放（付费才能播放）
	 * @param id 内容I的
	 * @param request 请求
	 * @param response 回应
	 * @param model 数据
	 */
	@RequestMapping(value = "/playVideo.jspx", method = RequestMethod.POST)
	public void playVideo(Integer id, HttpServletRequest request, HttpServletResponse response, ModelMap model){
		Content content = contentMng.findById(id);
        net.sf.json.JSONObject object = new net.sf.json.JSONObject();
        object.put("flag", true);
		if (content == null) {
			log.debug("Content id not found: {}", id);
			//return FrontUtils.pageNotFound(request, response, model);
            object.put("flag", false);
            ResponseUtils.renderJson(response, object.toString());
            return;
		}
        CmsUser user = CmsUtils.getUser(request);
        CmsSite site = content.getSite();
        model.addAttribute("content", content);
        model.addAttribute("site", site);
        model.addAttribute("channel", content.getChannel());
		Set<CmsGroup> groups = content.getViewGroupsExt();
		int len = groups.size();
		// 需要浏览权限
		if (len != 0) {
			// 已经登录但没有权限
			Integer gid = user.getGroup().getId();
			boolean right = false;
			for (CmsGroup group : groups) {
				if (group.getId().equals(gid)) {
					right = true;
					break;
				}
			}
			CmsConfig config=CmsUtils.getSite(request).getConfig();
			Boolean preview=config.getConfigAttr().getPreview();
			//无权限且不支持预览
			if (!right&&!preview) {
				String gname = user.getGroup().getName();
//				return FrontUtils.showMessage(request, model, GROUP_FORBIDDEN, gname);
                object.put("flag", false);
                object.put("reason", "1");
                ResponseUtils.renderJson(response, object.toString());
                return;
			}
			//无权限支持预览
			if(!right&&preview){
				model.addAttribute("preview", preview);
				model.addAttribute("groups", groups);
			}
		}

        //收费模式
        if(content.getCharge()){
            //非作者且未购买
            if(!content.getUser().equals(user)){
                //用户已登录判断是否已经购买
                boolean hasBuy=contentBuyMng.hasBuyContent(user.getId(), content.getId());
                if(!hasBuy){
                    try {
                        String rediretUrl="/content/buy.jspx?contentId="+content.getId();
                        if(StringUtils.isNotBlank(site.getContextPath())){
                            rediretUrl=site.getContextPath()+rediretUrl;
                        }
                        //response.sendRedirect(rediretUrl);
                        object.put("flag", false);
                        object.put("rediretUrl", rediretUrl);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        //视频播放
        if(content.getModel().getId() == 6 && (Boolean) object.get("flag")){
            //生成私有参数，不同API需要修改
            Map<String, String> privateParams = AliVedioApi.generatePrivateParamters(content.getAttr().get("videoId"));
            //生成公共参数，不需要修改
            Map<String, String> publicParams = AliVedioApi.generatePublicParamters();
            //生成OpenAPI地址，不需要修改
            String URL = AliVedioApi.generateOpenAPIURL(publicParams, privateParams);
            //发送HTTP GET 请求
            try {
                String json = AliVedioApi.httpGet(URL);
                JSONObject rs = JSON.parseObject(json);
                model.addAttribute("vid",rs.getJSONObject("VideoMeta").getString("VideoId"));
                model.addAttribute("playauth",rs.getString("PlayAuth"));
                model.addAttribute("cover",rs.getJSONObject("VideoMeta").getString("CoverURL"));

                List<Content> clist = contentMng.getListForduanTitle(site.getId(), content.getShortTitle());
                model.addAttribute("xgVideo",clist);

                object.put("flag", true);
                object.put("vid", rs.getJSONObject("VideoMeta").getString("VideoId"));
                object.put("playauth", rs.getString("PlayAuth"));
                object.put("cover", rs.getJSONObject("VideoMeta").getString("CoverURL"));
                //object.put("xgVideo", clist);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        FrontUtils.frontData(request, model, site);
        ResponseUtils.renderJson(response, object.toString());
        /*String equipment=(String) request.getAttribute("ua");
        if(StringUtils.isNotBlank(equipment)&&equipment.equals("mobile")){
            return content.getMobileTplContentOrDef(content.getModel());
        }
		return content.getTplContentOrDef(content.getModel());*/
	}

	private boolean existIndexPage(CmsSite site){
		boolean exist=false;
		if(site.getStaticIndex()){
			File indexPage;
			if(site.getIndexToRoot()){
				indexPage=new File(realPathResolver.get(INDEX_HTML));
			}else{
				indexPage=new File(realPathResolver.get(site.getStaticDir()+INDEX_HTML));
			}
			if(indexPage.exists()){
				exist=true; 
			}
		}
		return exist;
	}
	
	private String goToIndexPage(HttpServletRequest request,HttpServletResponse response,CmsSite site){
		String equipment=(String) request.getAttribute("ua");
		try {
			String ctx="";
			if(StringUtils.isNotBlank(site.getContextPath())){
				ctx=site.getContextPath();
			}
			if(site.getIndexToRoot()){
				
				if(StringUtils.isNotBlank(equipment)&&equipment.equals("mobile")){
					response.sendRedirect(ctx+INDEX_HTML_MOBILE);
				}else{
					response.sendRedirect(ctx+INDEX_HTML);
				}
			}else{
				if(StringUtils.isNotBlank(equipment)&&equipment.equals("mobile")){
					response.sendRedirect(ctx+site.getStaticMobileDir()+INDEX_HTML);
				}else{
					response.sendRedirect(ctx+site.getStaticDir()+INDEX_HTML);
				}
			}
		} catch (IOException e) {
			//e.printStackTrace();
		}
		return FrontUtils.getTplPath(request, site.getSolutionPath(),TPLDIR_INDEX, TPL_INDEX); 
	}
	
	@Autowired
	private ChannelMng channelMng;
	@Autowired
	private ContentMng contentMng;
	@Autowired
	private CmsKeywordMng cmsKeywordMng;
	@Autowired
	private RealPathResolver realPathResolver;
	@Autowired
	private ContentBuyMng contentBuyMng;
	@Autowired
	private SessionProvider session;
	@Autowired
	private CmsSiteMng siteMng;
}
